#pragma once

#include <memory>
#include <functional>

#include "Fields.hpp"

namespace MyRpc
{
    // 数据基类
    class BaseMessage
    {
    public:
        using msg_ptr = std::shared_ptr<BaseMessage>;
        virtual ~BaseMessage() {};
        virtual void SetMtype(MType mtype) { _mtype = mtype; }   // 设置消息类型
        virtual MType GetMtype() { return _mtype; }     // 获取消息类型
        virtual void SetId(const std::string& rid) { _rid = rid; }  //设置id
        virtual std::string GetId() { return _rid; }    //获取 id
        virtual std::string Serialize() = 0;        // 序列化
        virtual bool UnSerialize(const std::string& message) = 0;   // 反序列化
        virtual bool Check() = 0;

    private:
        MType _mtype;       // 消息类型
        std::string _rid;   // 请求id
    };


    // 缓冲区基类
    class BaseBuffer
    {
    public:
        //前4字节表示消息应有的长度
        using buf_ptr = std::shared_ptr<BaseBuffer>;
        virtual size_t ReadAbleSize() = 0;    // 返回当前缓冲区有多少数据
        virtual int32_t TryGetInt32() = 0;    // 尝试从缓冲区中获取前4字节
        virtual void RetrieveInt32() = 0;     // 删除缓冲区中前4字节 
        virtual int32_t ReadInt32() = 0;         // 从缓冲区中获取并删除前4字节,是 Retrieve 和 Try 的合并
        virtual std::string RetrieveAsLen(size_t len) = 0;  //从缓冲区中取出指定长度数据
    };


    // 协议基类
    class BaseProtocol
    {
    public:
        using pro_ptr = std::shared_ptr<BaseProtocol>;
        // 接收数据时的处理
        virtual bool CanProcessed(const BaseBuffer::buf_ptr& buf) = 0;  // 判断缓冲区数据能否处理
        virtual bool ProcessMessage(const BaseBuffer::buf_ptr& buf,BaseMessage::msg_ptr& msg) = 0; // 能够处理, 返回处理好的 msg
        // 发送数据时的处理
        virtual std::string Serialize(const BaseMessage::msg_ptr& msg) = 0; //将处理好的 msg 序列化
    };


    // 连接基类
    class BaseConnection
    {
    public:
        using con_ptr = std::shared_ptr<BaseConnection>;
        virtual void Send(const BaseMessage::msg_ptr& message) = 0; // 发送数据
        virtual void DisConnect() = 0;  // 断开连接
        virtual bool ConnectStatus() = 0;  // 连接状态 成功/失败/是否正常
    };


    // 用户在建立连接时自行选择设置三个回调函数
    using ConnectionCallBack = std::function<void(const BaseConnection::con_ptr&)>; // 连接回调函数
    using CloseConnCallBack = std::function<void(const BaseConnection::con_ptr&)>; // 关闭连接回调函数
    using AcceptMsgCallBack = std::function<void(const BaseConnection::con_ptr&,BaseMessage::msg_ptr&)>; // 用于接收消息, 使用BaseBuffer

    // 服务器基类
    class BaseServer
    {
    public:
        using server_ptr = std::shared_ptr<BaseServer>;
        virtual void SetConnCb(const ConnectionCallBack& conn_cb) { _server_conn_cb = conn_cb; }   // 设置连接回调函数
        virtual void SetCloseConnCb(const CloseConnCallBack& close_cb) { _server_close_cb = close_cb; }    // 设置关闭连接回调函数
        virtual void SetMsgCb(const AcceptMsgCallBack& msg_cb) { _server_msg_cb = msg_cb; }          // 设置接受消息回调函数
        virtual void Start() = 0;   // 运行服务器

    protected:
        ConnectionCallBack _server_conn_cb;
        CloseConnCallBack _server_close_cb;
        AcceptMsgCallBack _server_msg_cb;
    };


    // 客户端基类
    class BaseClient
    {
    public:
        using client_ptr = std::shared_ptr<BaseClient>;
        virtual void SetConnCb(const ConnectionCallBack& conn_cb) { _client_conn_cb = conn_cb; }   // 设置连接回调函数
        virtual void SetCloseConnCb(const CloseConnCallBack& close_cb) { _client_close_cb = close_cb; }    // 设置关闭连接回调函数
        virtual void SetMsgCb(const AcceptMsgCallBack& msg_cb) { _client_msg_cb = msg_cb; }          // 设置接受消息回调函数

        virtual void Connect() = 0; // 发起连接
        virtual void DisConnect() = 0; // 断开连接
        virtual bool Send(const BaseMessage::msg_ptr&) = 0; // 发送消息
        virtual BaseConnection::con_ptr GetConnect() = 0; // 获取连接对象
        virtual bool ConnectStatus() = 0; //连接状态

    protected:
        ConnectionCallBack _client_conn_cb;
        CloseConnCallBack _client_close_cb;
        AcceptMsgCallBack _client_msg_cb;
    };
}
